/*******************************************
 * Copyright 2007 Aphrodite Framework for javaME .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * Email : owner@aphroditeme.dev.java.net
 * Contributors:
 *     Kent Elton - initial API and implementation
 *******************************************/

package com.aphrodite.ui.widgets;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

//TODO add scroll bars, implement traverse method
/**
 * Image that is scrollable within the given width and height
 * 
 * @author kentelt
 * 
 */
public final class ScrollableImage extends TraversableWidget {

	private Image image;
	private int imageHeight;
	private int imageWidth;
	// touch properties
	private int lastPointerX = -1;
	private int lastPointerY = -1;

	private int steps = 5;
	// scroll properties
	private int translationX = 0;

	private int translationY = 0;

	public ScrollableImage(Theme theme, Image image, int width, int height) {
		super(theme, width, height);
		setImage(image);
	}

	public void cleanUp() {
		image = null;
	}

	public boolean moveDown() {
		boolean innerScroll = scrollImage(steps, steps);
		reDrawWidget();
		return innerScroll;
	}

	public boolean moveLeft() {
		boolean innerScroll = scrollImage(steps, steps);
		reDrawWidget();
		return innerScroll;
	}

	public boolean moveRight() {
		boolean innerScroll = scrollImage(steps, steps);
		return innerScroll;
	}

	public boolean moveUp() {
		boolean innerScroll = scrollImage(steps, steps);
		reDrawWidget();
		return innerScroll;
	}

	public boolean pointerDrag(int x, int y) {
		if (isVisible
				&& com.aphrodite.util.geom.GeomUtil.withinBounds(x, y, super.x, super.y, super.width, super.height)) {

			scrollImage(lastPointerX - x, lastPointerY - y);
			lastPointerX = x;
			lastPointerY = y;
			reDrawWidget();
			return true;
		}
		return false;
	}

	public boolean pointerPress(int x, int y) {
		if (isVisible
				&& com.aphrodite.util.geom.GeomUtil.withinBounds(x, y, super.x, super.y, super.width, super.height)) {
			lastPointerX = x;
			lastPointerY = y;
			return true;
		}
		return false;
	}

	public boolean pointerRelease(int x, int y) {
		if (isVisible
				&& com.aphrodite.util.geom.GeomUtil.withinBounds(x, y, super.x, super.y, super.width, super.height)) {
			lastPointerX = -1;
			lastPointerY = -1;
			return false;
		}
		return false;

	}

	public void render(final Graphics g) {
		if (!isVisible)
			return;
		capture(g, width, height, true);
		g.drawImage(image, -translationX, -translationY, Graphics.TOP | Graphics.LEFT);
		release(g, width, height, true);

	}

	private boolean scrollImage(final int deltaX, final int deltaY) {
		if (imageWidth > width) {
			translationX += deltaX;
			if (translationX < 0) {
				translationX = 0;
				// return false;
			} else if (translationX + width > imageWidth) {
				translationX = imageWidth - width;
				// return true;
			}
		}

		if (imageHeight > height) {
			translationY += deltaY;
			if (translationY < 0) {
				translationY = 0;
				// return false;
			} else if (translationY + height > imageHeight) {
				translationY = imageHeight - height;
				// return true;
			}

		}
		return true;

	}

	public void setImage(final Image image) {
		this.image = image;
		imageWidth = this.image.getWidth();
		imageHeight = this.image.getHeight();
		// touch properties
		lastPointerX = -1;
		lastPointerY = -1;

		// scroll properties
		translationX = 0;
		translationY = 0;
		reDrawWidget();
		stateChanged(this);

	}

	/**
	 * Set the steps (in pixels) to scroll.In the case of scrolling using
	 * directional keys. Step based scroll is not performed with touch screen
	 * based interactions
	 * 
	 * @param steps
	 *            Default is 5px
	 */
	public void setSteps(int steps) {
		this.steps = steps;
	}

	protected boolean traverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout) {
		return false;
	}

	protected void updateModel() {

	}

}
